package edu.asu.cse360.context;

import edu.asu.cse360.editor.DateTimePropertyEditor;
import edu.asu.cse360.service.ItemOrderService;
import edu.asu.cse360.service.AuthenticationService;
import edu.asu.cse360.service.EmployeeService;
import edu.asu.cse360.service.ItemReportService;
import edu.asu.cse360.service.MenuItemService;
import edu.asu.cse360.service.OrderService;
import edu.asu.cse360.service.OrderStatusService;
import edu.asu.cse360.service.PhotoService;
import edu.asu.cse360.service.RestaurantService;
import edu.asu.cse360.service.StaffReportService;
import edu.asu.cse360.service.TableService;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.CustomEditorConfigurer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class ServiceFactory {

    private static ApplicationContext context;
    private static boolean useClientServices;
    static{
        setUseClientServices(true);
    }

   

    private ServiceFactory(){}
    
    /**
     * @return the useClientServices
     */
    public static boolean isUseClientServices() {
        return useClientServices;
    }

    /**
     * @param aUseClientServices : if true, factory will return client implementations
     * of the services.
     */
    public static void setUseClientServices(boolean aUseMockServices) {
        useClientServices = aUseMockServices;
        if(useClientServices){
            context = getClientAppContext();
        }else{
            context = getRealAppContext();
        }
    }

    public static RestaurantService getRestaurantService(){
        return context.getBean(ServiceConfig.RESTAURANT_SVC_NAME, RestaurantService.class);
    }

    public static AuthenticationService getAuthenticationService(){
        return context.getBean(ServiceConfig.AUTHENTICATION_SVC_NAME, AuthenticationService.class);
    }

    public static MenuItemService getMenuItemService(){
        return context.getBean(ServiceConfig.MENU_ITEM_SVC_NAME, MenuItemService.class);
    }


    public static ItemOrderService getItemOrderService() {
       return context.getBean(ServiceConfig.ITEM_ORDER_SVC_NAME, ItemOrderService.class);
    }


    public static OrderStatusService getOrderStatusService() {
        return context.getBean(ServiceConfig.ORDER_STATUS_SVC_NAME, OrderStatusService.class);
    }

    public static PhotoService getPhotoService() {
        return context.getBean(ServiceConfig.PHOTO_SVC_NAME, PhotoService.class);
    }


    public static TableService getTableService() {
        return context.getBean(ServiceConfig.TABLE_SVC_NAME, TableService.class);
    }

    public static ItemReportService getItemReportService(){
        return context.getBean(ServiceConfig.ITEM_REPORT_SVC_NAME, ItemReportService.class);
    }

    public static OrderService getOrderService() {
        return context.getBean(ServiceConfig.ORDER_SVC_NAME, OrderService.class);
    }

    public static StaffReportService getStaffReportService(){
        return context.getBean(ServiceConfig.STAFF_REPORT_SVC_NAME, StaffReportService.class);
    }

    public static EmployeeService getEmployeeService(){
        return context.getBean(ServiceConfig.EMPLOYEE_SVC_NAME, EmployeeService.class);
    }

    private static ApplicationContext getRealAppContext(){
        return new AnnotationConfigApplicationContext(RemoteServiceConfig.class);
    }

    private static ApplicationContext getClientAppContext(){
        AnnotationConfigApplicationContext clientContext = new AnnotationConfigApplicationContext();
        clientContext.addBeanFactoryPostProcessor(getCustomerEditorConfigurer());
        clientContext.register(ClientServiceConfig.class);
        clientContext.refresh();
        return clientContext;
    }

    private static BeanFactoryPostProcessor getCustomerEditorConfigurer(){
        CustomEditorConfigurer cec = new CustomEditorConfigurer();
        Map<String, Object> editorsMap = new HashMap<String, Object>();
        editorsMap.put("org.joda.time.DateTime", new DateTimePropertyEditor());
        cec.setCustomEditors(editorsMap);
        return cec;
    }

}
